home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / comm / wnos5src.zip / SESSION.C < prev    next >
Text File  |  1993-08-09  |  9KB  |  451 lines

  1. /* Session control */
  2. #include <stdio.h>
  3. #include "global.h"
  4. #include "config.h"
  5. #include "mbuf.h"
  6. #include "proc.h"
  7. #include "ftp.h"
  8. #include "icmp.h"
  9. #include "telnet.h"
  10. #include "tty.h"
  11. #include "session.h"
  12. #include "hardware.h"
  13. #include "socket.h"
  14. #include "cmdparse.h"
  15. #include "commands.h"
  16. #include "files.h"
  17. #include "usock.h"
  18.  
  19. struct session *Sessions, *Current, *Lastcurr;
  20. extern struct proc *Display;
  21.  
  22. #define LWRAP    63
  23.  
  24. char Notval[] = "Not a valid control block\n";
  25. char Nosess[] = "Too many sessions\n";
  26.  
  27. char *Sestypes[] = {
  28.     "",
  29.     "Telnet",
  30.     "FTP",
  31.     "AX25",
  32.     "Finger",
  33.     "Ping",
  34.     "NET/ROM",
  35.     "Command",
  36.     "More",
  37.     "Hopcheck",
  38.     "Tip",
  39.     "PPP PAP",
  40.     "Trace",
  41.     "RawIF"
  42. };
  43.  
  44. /* Convert a character string containing a decimal session index number
  45.  * into a pointer. If the arg is NULLCHAR, use the current default session.
  46.  * If the index is out of range or unused, return NULLSESSION.
  47.  */
  48. struct session *
  49. sessptr(char *cp)
  50. {
  51.     unsigned int i;
  52.     struct session *sp;
  53.  
  54.     if(cp == NULLCHAR) {
  55.         sp = Lastcurr;
  56.     } else if((i = atoi(cp)) >= Nsessions) {
  57.         sp = NULLSESSION;
  58.     } else {
  59.         sp = &Sessions[i + 1];
  60.     }
  61.     if(sp == NULLSESSION || sp->type == FREE) {
  62.         tputs("Invalid or inactive session\n");
  63.         return NULLSESSION;
  64.     }
  65.     return sp;
  66. }
  67.  
  68. /* Select and display sessions */
  69. int
  70. dosession(int argc,char **argv,void *p)
  71. {
  72.     struct sockaddr fsocket;
  73.     int i = SOCKSIZE, k, s, r, t;
  74.     char *cp, limbo[] = "Limbo!";
  75.  
  76.     struct session *sp = (struct session *)p;
  77.  
  78.     if(argc > 1) {
  79.         if((sp = sessptr(argv[1])) != NULLSESSION) {
  80.             go(0,0,sp);
  81.         }
  82.         return 0;
  83.     }
  84.     tputs(" #  S#  Type     Rcv-Q Snd-Q State        Remote socket\n");
  85.  
  86.     for(sp = Sessions; sp < &Sessions[Nsessions]; sp++) {
  87.         if(sp->type == FREE || sp->type == COMMAND || sp->type == TRACESESSION) {
  88.             continue;
  89.         }
  90.         /* Rcv-Q includes output pending at the screen driver */
  91.         r = socklen(sp->output,1);
  92.         t = 0;
  93.         cp = NULLCHAR;
  94.  
  95.         if((s = sp->s) != -1){
  96.             k = getpeername(s,(char *)&fsocket,&i);
  97.             r += socklen(s,0);
  98.             t += socklen(s,1);
  99.             cp = sockstate(s);
  100.         }
  101.  
  102.         tprintf("%c%-3u%-4d",
  103.             (Lastcurr == sp) ? '*' : ' ',
  104.             (unsigned)(sp - Sessions) - 1,
  105.             s);
  106.         tprintf("%-8s%6d%6d %-13s%s",
  107.             Sestypes[sp->type],
  108.             r,
  109.             t,
  110.             (cp != NULLCHAR) ? cp : limbo,
  111.             (sp->name != NULLCHAR) ? sp->name : "");
  112.  
  113.         if(sp->s != -1 && k == 0) {
  114.             tprintf(" (%s)",psocket(&fsocket));
  115.         }
  116.         tputs("\n");
  117.  
  118.         if(sp->type == FTP && (s = sp->cb.ftp->data) != -1){
  119.             /* Display data channel, if any */
  120.             k = getpeername(s,(char *)&fsocket,&i);
  121.             r = socklen(s,0);
  122.             t = socklen(s,1);
  123.             cp = sockstate(s);
  124.  
  125.             tprintf("    %-4d%-8s%6d%6d %-13s%s",
  126.                 s,
  127.                 Sestypes[sp->type],
  128.                 r,
  129.                 t,
  130.                 (cp != NULLCHAR) ? cp : limbo,
  131.                 (sp->name != NULLCHAR) ? sp->name : "");
  132.  
  133.             if(k == 0) {
  134.                 tprintf(" (%s)",psocket(&fsocket));
  135.             }
  136.             tputs("\n");
  137.         }
  138.         if(sp->rfile != NULLCHAR) {
  139.             tprintf("    Record: %s\n",sp->rfile);
  140.         }
  141.         if(sp->ufile != NULLCHAR) {
  142.             tprintf("    Upload: %s\n",sp->ufile);
  143.         }
  144.     }
  145.     return 0;
  146. }
  147.  
  148. /* Resume current session, and wait for it */
  149. int
  150. go(int argc,char **argv,void *p)
  151. {
  152.     struct session *sp = (struct session *)p, *sptmp = Current;
  153.  
  154.     if(sp == NULLSESSION
  155.       || sp->type == FREE
  156.       || (sptmp == Trace && sp->type == TRACESESSION)
  157.       || (sptmp == Command && sp->type == COMMAND)) {
  158.         return 0;
  159.     }
  160.     swapscreen(sptmp,sp);
  161.     psignal(sp,0);
  162.     Current = sp;
  163.     return 0;
  164. }
  165.  
  166. int
  167. doclose(int argc,char **argv,void *p)
  168. {
  169.     struct session *sp = (struct session *)p;
  170.  
  171.     if(argc > 1) {
  172.         sp = sessptr(argv[1]);
  173.     }
  174.     if(sp == NULLSESSION) {
  175.         return -1;
  176.     }
  177.     if(sp->type == FTP || sp->type == MORE) {
  178.         /* Unwedge anyone waiting for a domain resolution, etc */
  179.         alert(sp->proc,(void *)EABORT);
  180.     }
  181.     shutdown(sp->s,1);
  182.     return 0;
  183. }
  184.  
  185. int
  186. doreset(int argc,char **argv,void *p)
  187. {
  188.     struct session *sp = (struct session *)p;
  189.  
  190.     if(argc > 1) {
  191.         sp = sessptr(argv[1]);
  192.     }
  193.     if(sp == NULLSESSION) {
  194.         return -1;
  195.     }
  196.     /* Unwedge anyone waiting for a domain resolution, etc */
  197.     alert(sp->proc,(void *)EABORT);
  198.  
  199.     if(sp->type == FTP) {
  200.         shutdown(sp->cb.ftp->data,2);
  201.     }
  202.     shutdown(sp->s,2);
  203.     return 0;
  204. }
  205.  
  206. int
  207. dokick(int argc,char **argv,void *p)
  208. {
  209.     struct session *sp = (struct session *)p;
  210.  
  211.     if(argc > 1) {
  212.         sp = sessptr(argv[1]);
  213.     }
  214.     if(sp == NULLSESSION){
  215.         return -1;
  216.     }
  217.     if(sp->type == FTP) {
  218.         sockkick(sp->cb.ftp->data);
  219.     }
  220.     sockkick(sp->s);
  221.     return 0;
  222. }
  223.  
  224. struct session *
  225. newsession(char *name,int type,int Flag)
  226. {
  227.     int i;
  228.     struct session *sp;
  229.  
  230.     for(i = 0, sp = Sessions; i < Nsessions; sp++, i++) {
  231.         if(sp->type == FREE) {
  232.             break;
  233.         }
  234.     }
  235.     if(i == Nsessions) {
  236.         return NULLSESSION;
  237.     }
  238.     sp->proc = Curproc;
  239.     sp->type = type;
  240.     sp->s = -1;
  241.  
  242.     if(name != NULLCHAR) {
  243.         sp->name = strxdup(name);
  244.     }
  245.     /* Create standard input and output sockets. Output is
  246.      * translated to local end-of-line by default
  247.      */
  248.     Curproc->input = sp->input = socket(AF_LOCAL,SOCK_STREAM,0);
  249.     seteol(Curproc->input,Eol);
  250.     sockmode(Curproc->input,SOCK_BINARY);
  251.  
  252.     Curproc->output = sp->output = socket(AF_LOCAL,SOCK_STREAM,0);
  253.     seteol(Curproc->output,Eol);
  254.     sockmode(Curproc->output,SOCK_ASCII);
  255.  
  256.     /* on by default */
  257.     sp->ttystate.crnl = sp->ttystate.edit = sp->ttystate.echo = 1;
  258.  
  259.     /* off by default */
  260.     sp->flowmode = sp->morewait = sp->cont = 0;
  261.  
  262.     sp->split = Flag & SPLIT;
  263.     sp->swap = Flag & SWAP;
  264.     sp->lwrap = LWRAP;
  265.     sp->row = (sp->split) ? Nrows - 5 : Nrows - 3;
  266.     newscreen(sp);
  267.  
  268.     if(sp->swap) {
  269.         swapscreen(Current,sp);
  270.         Current = sp;
  271.     }
  272.     return sp;
  273. }
  274.  
  275. void
  276. freesession(struct session *sp)
  277. {
  278.     if(sp == NULLSESSION)
  279.         return;
  280.  
  281.     usflush(sp->output);
  282.     pwait(NULL);
  283.  
  284.     if(sp->proc1 != NULLPROC) {
  285.         killproc(sp->proc1);
  286.         sp->proc1 = NULLPROC;
  287.     }
  288.     if(sp->proc2 != NULLPROC) {
  289.         killproc(sp->proc2);
  290.         sp->proc2 = NULLPROC;
  291.     }
  292.     free_p(sp->ttystate.line);
  293.     sp->ttystate.line = NULLBUF;
  294.  
  295.     if(sp->s != -1) {
  296.         close_s(sp->s);
  297.     }
  298.     if(sp->record != NULLFILE) {
  299.         Fclose(sp->record);
  300.         xfree(sp->rfile);
  301.     }
  302.     if(sp->upload != NULLFILE) {
  303.         Fclose(sp->upload);
  304.         xfree(sp->ufile);
  305.     }
  306.     if(sp->name != NULLCHAR)
  307.         xfree(sp->name);
  308.     sp->name = NULLCHAR;
  309.     sp->rfile = NULLCHAR;
  310.     sp->record = NULLFILE;
  311.     sp->ufile = NULLCHAR;
  312.     sp->upload = NULLFILE;
  313.  
  314.     close_s(sp->input);
  315.     close_s(sp->output);
  316.     freescreen(sp);
  317.  
  318.     sp->type = FREE;
  319.  
  320.     if(Current == sp){
  321.         Current = (Lastcurr == Trace) ? Trace : Command;
  322.         swapscreen(NULLSESSION,Current);
  323.         alert(Display,(void *)1);
  324.     }
  325.     if(Lastcurr == sp)
  326.         Lastcurr = NULLSESSION;
  327. }
  328.  
  329. /* Control session recording */
  330. int
  331. dorecord(int argc,char **argv,void *p)
  332. {
  333.     struct session *sp = (struct session *)p;
  334.  
  335.     if(argc > 2) {
  336.         sp = sessptr(argv[1]);
  337.         argc--;
  338.         argv++;
  339.     }
  340.     if(sp == NULLSESSION) {
  341.         return -1;
  342.     }
  343.     if(argc > 1){
  344.         if(sp->rfile != NULLCHAR){
  345.             Fclose(sp->record);
  346.             sp->record = NULLFILE;
  347.             xfree(sp->rfile);
  348.             sp->rfile = NULLCHAR;
  349.         }
  350.         /* Open new record file, unless file name is "off", which means
  351.          * disable recording
  352.          */
  353.         if(strcmp(argv[1],"off") != 0){
  354.             if((sp->record = Fopen(argv[1],
  355.               (sockmode(sp->output,-1) == SOCK_ASCII) ? APPEND_TEXT : APPEND_BINARY,
  356.               0,1)) == NULLFILE) {
  357.                 return -1;
  358.             } else {
  359.                 sp->rfile = strxdup(argv[1]);
  360.             }
  361.         }
  362.     }
  363.     if(sp->rfile != NULLCHAR) {
  364.         tprintf("Recording into %s\n",sp->rfile);
  365.     } else {
  366.         tputs("Recording off\n");
  367.     }
  368.     return 0;
  369. }
  370.  
  371. int
  372. dowrap(int argc,char **argv,void *p)
  373. {
  374.     struct session *sp = (struct session *)p;
  375.     int16 i;
  376.  
  377.     if(argc > 1 && atoi(argv[1]) < 30) {
  378.         sp = sessptr(argv[1]);
  379.         argc--;
  380.         argv++;
  381.     }
  382.     if(sp == NULLSESSION) {
  383.         return -1;
  384.     }
  385.     i = sp->lwrap;
  386.     setintrc(&i,"Wrap",argc,argv,30,132);
  387.     sp->lwrap = i;
  388.  
  389.     return 0;
  390. }
  391.  
  392. /* Control file transmission */
  393. int
  394. doupload(int argc,char **argv,void *p)
  395. {
  396.     struct session *sp = (struct session *)p;
  397.  
  398.     if(argc > 2) {
  399.         sp = sessptr(argv[1]);
  400.         argc--;
  401.         argv++;
  402.     }
  403.     if(sp == NULLSESSION) {
  404.         return -1;
  405.     }
  406.     if(argc < 2) {
  407.         tprintf("Uploading %s\n",(sp->ufile != NULLCHAR) ? sp->ufile : "off");
  408.         return 0;
  409.     }
  410.     if(strcmp(argv[1],"off") == 0 && sp->upload != NULLFILE) {
  411.         /* Abort upload */
  412.         Fclose(sp->upload);
  413.         sp->upload = NULLFILE;
  414.         xfree(sp->ufile);
  415.         sp->ufile = NULLCHAR;
  416.         return 0;
  417.     }
  418.     /* Open upload file */
  419.     if((sp->upload = Fopen(argv[1],READ_TEXT,0,1)) == NULLFILE) {
  420.         return -1;
  421.     }
  422.     sp->ufile = strxdup(argv[1]);
  423.  
  424.     /* All set, invoke the upload process */
  425.     sp->proc2 = newproc("upload",1024,upload,0,sp,NULL,0);
  426.     return 0;
  427. }
  428.  
  429. /* File uploading task */
  430. static void
  431. upload(int unused,void *sp1,void *p)
  432. {
  433.     char line[LINELEN];
  434.     struct session *sp = (struct session *)sp1;
  435.  
  436.     /* Disable newline buffering for the duration */
  437.     int oldf = setflush(sp->s,-1);
  438.  
  439.     while(sp->ufile != NULLCHAR && fgets(line,LINELEN,sp->upload) != NULL) {
  440.         usputs(sp->s,line);
  441.     }
  442.     usflush(sp->s);
  443.     setflush(sp->s,oldf);
  444.  
  445.     Fclose(sp->upload);
  446.     sp->upload = NULLFILE;
  447.     xfree(sp->ufile);
  448.     sp->ufile = NULLCHAR;
  449.     sp->proc2 = NULLPROC;
  450. }
  451.